<template>
  <n-card :bordered="false" class="proCard">
    <div style="padding-bottom: 5px">
      <n-space justify="space-between">
        <div>
          <div v-if="!isPreview">
            <n-button v-show="!isRename" @click="toRenameHandler" icon-placement="right" type="info" text ghost>
              <template #icon>
                <Pencil />
              </template>
              {{ formData?.name || '新的文件' }}
            </n-button>
            <n-input-group v-show="isRename">
              <n-input ref="renameInputRef" @keyup.enter="endRename" @blur="endRename" v-model:value="formData.name" :style="{ width: '50%' }" />
              <n-input-group-label>.md</n-input-group-label>
            </n-input-group>
          </div>
          <div v-else>
            <n-button type="info" icon-placement="right" text ghost>
              <template #icon>
                <FileTwotone />
              </template>
              {{ formData?.name || '未命名' }}
            </n-button>
          </div>
        </div>
        <div>
          <n-button style="margin-right: 10px" @click="isPreview = !isPreview" type="primary" text ghost>
            <template #icon v-if="!isPreview">
              <EyeTwotone />
            </template>
            <template #icon v-else>
              <EyeInvisibleTwotone />
            </template>
            <span v-if="!isPreview">开启MarkDown预览</span>
            <span v-else>关闭MarkDown预览</span>
          </n-button>
        </div>
      </n-space>
    </div>
    <v-md-editor
      v-model="content"
      :mode="isPreview ? 'preview' : 'editable'"
      :left-toolbar="leftToolbar"
      :height="height"
      :disabled-menus="[]"
      @change="editorChangeHandler"
      @save="editorSaveHandler"
      @upload-image="uploadImageHandler"
      @image-click="imageClickHandler"
    ></v-md-editor>

    <n-modal
      v-model:show="isShowModal"
      style="width: 400px"
      preset="card"
      title="选择文件保存目录"
      size="small"
      :bordered="false"
    >
      <n-input-group>
        <n-input-group-label>将该文件保存到</n-input-group-label>
        <n-tree-select
          key-field="id"
          label-field="name"
          :options="options"
          :default-expanded-keys="['ROOT']"
          @update:value="handleUpdateValue"
        />
      </n-input-group>

      <template #action>
        <n-button @click="isShowModal = false" type="primary" style="float: right">
          确定
        </n-button>
      </template>
    </n-modal>
  </n-card>
</template>

<script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { getFolderList, markdownInfo, markdownUpload } from "@/api/worker/fileSystem";
import { upload2MarkdownPicture } from "@/api/console/picture";
import { useEditorMdStore } from "@/store/modules/editorMd";
import { useGlobSetting } from "@/hooks/setting";
import { Pencil } from '@vicons/tabler';
import { EyeTwotone, EyeInvisibleTwotone, FileTwotone } from '@vicons/antd';
import { InputInst, useDialog, useMessage } from 'naive-ui'
import { IFolder } from "@/views/worker/fileSystem/module-type";
import { computedMd5ByStr } from "@/utils/file";
import { useRoute, useRouter } from "vue-router";
import { api as viewerApi } from "v-viewer"

const editorEditorStore = useEditorMdStore()
const globalSetting = useGlobSetting()
const dialog = useDialog()
const message = useMessage()
const route = useRoute()
const router = useRouter()

const isRename = ref(false)
const renameInputRef = ref<InputInst | null>(null)
const content = ref('')
const isPreview = ref(false)
const height = ref('400px')
const leftToolbar = ref('undo redo clear | emoji h bold italic strikethrough quote todo-list | ul ol table hr | link image code | save')

// 用来记录文件原本的信息
const globalEditorData = ref({
  id: '',
  identifier: '',
  dirId: '',
  name: '',
  content: '',
})
// 用来记录需要提交的信息
const formData = ref({
  id: '',
  identifier: '',
  dirId: '',
  name: '',
  content: '',
})
const initData = async () => {
  const params = route.params
  if (params.id) {
    // @ts-ignore
    const data = await markdownInfo(params.id)
    globalEditorData.value = data
    content.value = data.content
    Object.assign(formData.value, data)
  } else {
    const c = editorEditorStore.getContent
    if (c) {
      content.value = c
      message.info('加载了缓存在本地的内容')
    }
  }
}

onMounted(async () => {
  await initData()
  handleResize(); // 执行一次以初始化高度
  window.addEventListener('resize', handleResize);
});

const toRenameHandler = () => {
  // 判断当前文件名是否携带 .md 后缀, 有则去除
  let name = formData.value.name
  if (name.endsWith(".md")) {
    formData.value.name = name.substring(0, name.length - 3)
  }
  isRename.value = true;
  setTimeout(() => {
    renameInputRef.value?.focus()
  }, 100)
}

const endRename = () => {
  let name = formData.value.name
  if (name && !name.endsWith(".md")) {
    formData.value.name = name + '.md';
  }
  isRename.value = false;
}

const editorChangeHandler = (text, html) => {
  // 如果在一个新的编辑器中编辑，才进行本地存储
  if (text && !globalEditorData.value.id) {
    editorEditorStore.setContent(text)
  }
}

const editorSaveHandler = (text, html) => {
  const _handler = async () => {
    // 没有指定保存目录就去选择
    if (!formData.value.dirId) {
      options.value = [await getFolderList()]
      isShowModal.value = true;
      return;
    }
    // 没有指定文件名就要指定
    if (!formData.value.name) {
      isRename.value = true
      setTimeout(() => {
        renameInputRef.value?.focus()
      }, 100)
      return message.warning('请填写文件名')
    }

    formData.value.identifier = computedMd5ByStr(content.value)
    formData.value.content = content.value
    // 如果是更新数据, 那么进行检查
    if (formData.value.id) {
      // 内容没有变化且文件名没有改动就不上传
      if (formData.value.identifier === globalEditorData.value.identifier &&
          formData.value.content === globalEditorData.value.content &&
          formData.value.name === globalEditorData.value.name) {
        return;
      }
    }
    const data = await markdownUpload(formData.value.dirId, {
      id: formData.value.id,
      identifier: formData.value.identifier,
      name: formData.value.name,
      content: formData.value.content
    })
    if (data) {
      await router.push({params: {id: data?.id}})
    }
    message.info('保存成功!')
  }
  _handler()
}

const uploadImageHandler = async (event, insertImage, files) => {
  for (let i = 0; i < files.length; i++) {
    let file = files[i];
    const data = await upload2MarkdownPicture(file)

    insertImage({
      url: `${window.location.protocol}//${window.location.host}${globalSetting.urlPrefix}${data}`,
      desc: `${file.name || '图片'}`,
      width: 'auto',
      height: 'auto'
    });
  }
}

const imageClickHandler = (images, currentIndex) => {
  // images: 当前md文件中的所有图片地址
  // currentIndex: 当前点击的图片的索引
  viewerApi({
    images: images,
    options: {
      toolbar: true,
      initialViewIndex: currentIndex
    },
  })
}

const isShowModal = ref(false)
const options = ref<IFolder[]>([])
const handleUpdateValue = (value, option) => {
  formData.value.dirId = value
}

const handleResize = () => {
  let h = window.innerHeight;
  height.value = `${h - 130 - 55}px`
}

onBeforeUnmount(() => {
  // 触发组件销毁时应再次触发保存事件
  if (globalEditorData.value.id) {
    editorSaveHandler(content.value, null)
  }
  window.removeEventListener('resize', handleResize);
});
</script>

<style scoped>

</style>
